<?php

namespace app\service;

use app\model\Account;
use app\model\User;
use app\model\SystemConfig;
use Exception;

class NotificationService
{
    /**
     * 获取用户的所有通知
     */
    public function getUserNotifications($userId)
    {
        $notifications = [];

        // 检查密码过期提醒
        $expiringAccounts = $this->getExpiringPasswordNotifications($userId);
        $notifications = array_merge($notifications, $expiringAccounts);

        // 检查已过期密码
        $expiredAccounts = $this->getExpiredPasswordNotifications($userId);
        $notifications = array_merge($notifications, $expiredAccounts);

        // 检查长时间未使用的账号
        $unusedAccounts = $this->getUnusedAccountNotifications($userId);
        $notifications = array_merge($notifications, $unusedAccounts);

        // 按优先级排序
        usort($notifications, function ($a, $b) {
            return $b['priority'] - $a['priority'];
        });

        return $notifications;
    }

    /**
     * 获取即将过期的密码通知
     */
    public function getExpiringPasswordNotifications($userId, $days = 7)
    {
        $notifications = [];

        $accounts = Account::getExpiringAccounts($userId, $days);

        foreach ($accounts as $account) {
            $daysUntilExpire = $this->getDaysUntilExpire($account->expires_at);

            $priority = 3; // 中等优先级
            if ($daysUntilExpire <= 1) {
                $priority = 5; // 高优先级
            } elseif ($daysUntilExpire <= 3) {
                $priority = 4;
            }

            $notifications[] = [
                'id' => 'expiring_' . $account->id,
                'type' => 'password_expiring',
                'priority' => $priority,
                'title' => '密码即将过期',
                'message' => "账号「{$account->title}」的密码将在 {$daysUntilExpire} 天后过期",
                'account_id' => $account->id,
                'account_title' => $account->title,
                'days_until_expire' => $daysUntilExpire,
                'expires_at' => $account->expires_at,
                'action' => 'update_password',
                'action_text' => '立即更新',
                'created_at' => date('Y-m-d H:i:s')
            ];
        }

        return $notifications;
    }

    /**
     * 获取已过期密码通知
     */
    public function getExpiredPasswordNotifications($userId)
    {
        $notifications = [];

        $accounts = Account::getExpiredAccounts($userId);

        foreach ($accounts as $account) {
            $daysExpired = $this->getDaysExpired($account->expires_at);

            $notifications[] = [
                'id' => 'expired_' . $account->id,
                'type' => 'password_expired',
                'priority' => 5, // 高优先级
                'title' => '密码已过期',
                'message' => "账号「{$account->title}」的密码已过期 {$daysExpired} 天",
                'account_id' => $account->id,
                'account_title' => $account->title,
                'days_expired' => $daysExpired,
                'expires_at' => $account->expires_at,
                'action' => 'update_password',
                'action_text' => '立即更新',
                'created_at' => date('Y-m-d H:i:s')
            ];
        }

        return $notifications;
    }

    /**
     * 获取长时间未使用账号通知
     */
    public function getUnusedAccountNotifications($userId, $days = 90)
    {
        $notifications = [];

        $threshold = date('Y-m-d H:i:s', strtotime("-{$days} days"));

        $accounts = Account::where('user_id', $userId)
            ->where(function ($query) use ($threshold) {
                $query->where('last_used_at', '<', $threshold)
                    ->whereOr('last_used_at', null);
            })
            ->limit(5)
            ->select();

        foreach ($accounts as $account) {
            $daysSinceUse = $this->getDaysSinceLastUse($account->last_used_at);

            $notifications[] = [
                'id' => 'unused_' . $account->id,
                'type' => 'account_unused',
                'priority' => 2, // 低优先级
                'title' => '账号长时间未使用',
                'message' => "账号「{$account->title}」已 {$daysSinceUse} 天未使用",
                'account_id' => $account->id,
                'account_title' => $account->title,
                'days_since_use' => $daysSinceUse,
                'last_used_at' => $account->last_used_at,
                'action' => 'view_account',
                'action_text' => '查看详情',
                'created_at' => date('Y-m-d H:i:s')
            ];
        }

        return $notifications;
    }

    /**
     * 获取通知统计
     */
    public function getNotificationStats($userId)
    {
        $stats = [
            'total' => 0,
            'expiring' => 0,
            'expired' => 0,
            'unused' => 0,
            'high_priority' => 0
        ];

        $notifications = $this->getUserNotifications($userId);

        $stats['total'] = count($notifications);

        foreach ($notifications as $notification) {
            if ($notification['type'] === 'password_expiring') {
                $stats['expiring']++;
            } elseif ($notification['type'] === 'password_expired') {
                $stats['expired']++;
            } elseif ($notification['type'] === 'account_unused') {
                $stats['unused']++;
            }

            if ($notification['priority'] >= 4) {
                $stats['high_priority']++;
            }
        }

        return $stats;
    }

    /**
     * 计算距离过期的天数
     */
    private function getDaysUntilExpire($expiresAt)
    {
        if (!$expiresAt) return null;

        $now = time();
        $expireTime = strtotime($expiresAt);

        return max(0, ceil(($expireTime - $now) / 86400));
    }

    /**
     * 计算已过期天数
     */
    private function getDaysExpired($expiresAt)
    {
        if (!$expiresAt) return null;

        $now = time();
        $expireTime = strtotime($expiresAt);

        return max(0, ceil(($now - $expireTime) / 86400));
    }

    /**
     * 计算距上次使用天数
     */
    private function getDaysSinceLastUse($lastUsedAt)
    {
        if (!$lastUsedAt) {
            return 999; // 从未使用
        }

        $now = time();
        $lastUseTime = strtotime($lastUsedAt);

        return ceil(($now - $lastUseTime) / 86400);
    }

    /**
     * 发送密码过期邮件提醒（可选功能）
     */
    public function sendExpirationEmailReminder($userId)
    {
        $user = User::find($userId);
        if (!$user || !$user->email) {
            return false;
        }

        $notifications = $this->getExpiringPasswordNotifications($userId, 7);
        $expiredNotifications = $this->getExpiredPasswordNotifications($userId);

        if (empty($notifications) && empty($expiredNotifications)) {
            return false;
        }

        // TODO: 实现邮件发送逻辑
        // 这里只是示例，实际需要配置邮件服务

        return true;
    }

    /**
     * 批量更新过期密码
     */
    public function batchUpdateExpirationDate($userId, $accountIds, $expiresAt)
    {
        if (empty($accountIds)) {
            throw new Exception('请选择要更新的账号');
        }

        $count = Account::where('user_id', $userId)
            ->whereIn('id', $accountIds)
            ->update(['expires_at' => $expiresAt]);

        return $count;
    }

    /**
     * 设置默认密码过期时间
     */
    public function setDefaultPasswordExpiration($userId, $accountId, $days = null)
    {
        if (!$days) {
            // 从系统配置获取默认天数
            $config = SystemConfig::where('key', 'password_expire_days')->find();
            $days = $config ? intval($config->value) : 90;
        }

        $account = Account::where('id', $accountId)
            ->where('user_id', $userId)
            ->find();

        if (!$account) {
            throw new Exception('账号不存在');
        }

        $expiresAt = date('Y-m-d H:i:s', strtotime("+{$days} days"));
        $account->expires_at = $expiresAt;
        $account->save();

        return $account;
    }
}
